﻿using PaperMaster.Chess.Bell;
using PaperMaster.Chess.CardSpace;
using PaperMaster.Chess.PieceSpace;
using PaperMaster.Model;
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PaperMaster.Info;

namespace PaperMaster.Chess.CardSpace
{
    /// <summary>
    /// 该类负责发牌、洗牌、出牌
    /// </summary>
    public class PileController:IFightBeginCommand,IFightEndCommand
    {
        protected ICardModel _cardModel;
        public PileController()
        {
            _cardModel = ModelContainer.Get<ICardModel>();
            RegisterEvents();
        }
        ~PileController()
        {
            UnRegisterEvents();
        }
        protected virtual void RegisterEvents()
        {
            PlayerTurnBeginEvent.Register(OnPlayerTurnBegin);
            PlayerTurnEndEvent.Register(OnPlayerTurnEnd);
        }
        protected virtual void UnRegisterEvents()
        {
            PlayerTurnBeginEvent.Unregister(OnPlayerTurnBegin);
            PlayerTurnEndEvent.Unregister(OnPlayerTurnEnd);
        }
        #region 事件、指令响应函数
        void OnFightBegin() {
            ClearTiles();
            CreatePile();
            DrawCard(5);
        }
        void OnFightEnd()
        {
        }
        void OnPlayerTurnBegin()
        {
            DrawCard(5);
        }
        void OnPlayerTurnEnd()
        {
            DiscardAllHand();
        }
        #endregion
        #region 接口
        public void FightEndExecute()
        {
            OnFightEnd();
        }
        public void FightBeginExecute()
        {
            OnFightBegin();
        }
        /// <summary>
        /// 从抽牌堆中抽牌
        /// </summary>
        /// <param name="count">要抽的牌数</param>
        public void DrawCard(int count)
        {
            for (int i = 0; i < count; i++)
            {
                if (_cardModel.drawPile.Count > 0)
                {
                    ///抽牌堆未空
                    ///直接从牌堆顶抽一张牌
                }
                else
                {
                    ///抽牌堆已空
                    ///先将弃牌堆吸入抽牌堆，再抽一张牌
                    Shuffle();
                }
                if (_cardModel.drawPile.Count < 1)
                {
                    ///洗牌后抽牌堆仍然没牌，说明总牌数已经不够，停止抽牌
                    break;
                }
                CardControllerBase card = _cardModel.cardFactory.Produce(_cardModel.drawPile[_cardModel.drawPile.Count - 1]).GetComponent<CardViewController>().controller;
                card.DrawIn();
                _cardModel.hand.Add(card);
                _cardModel.drawPile.RemoveAt(_cardModel.drawPile.Count - 1);
            }
        }
        /// <summary>
        /// 弃掉所有手牌
        /// </summary>
        public void DiscardAllHand()
        {
            foreach(var content in _cardModel.hand)
            {
                content.WashedAway();
                DiscardCard(content);
                MonoBehaviour.Destroy(content.model.viewController.gameObject);
            }
            _cardModel.hand.Clear();
        }
        /// <summary>
        /// 弃掉一张手牌
        /// </summary>
        /// <param name="index">要弃掉的手牌编号</param>
        public void DiscardCard(int index)
        {
            if (index < _cardModel.hand.Count)
            {
                _cardModel.hand[index].WashedAway();
                DiscardCard(_cardModel.hand[index]);
                MonoBehaviour.Destroy(_cardModel.hand[index].model.viewController.gameObject);
                _cardModel.hand.RemoveAt(index);
            }
        }
        /// <summary>
        /// 洗牌，将弃牌堆中的所有牌洗入抽牌堆
        /// </summary>
        public void Shuffle()
        {
            int count = _cardModel.discardPile.Count;
            List<CardModelBase> tempLibrary = new List<CardModelBase>();
            foreach (var content in _cardModel.discardPile)
            {
                tempLibrary.Add(content);
            }
            System.Random r = new System.Random();
            for (int i = 0; i < count; i++)
            {
                int choosenIndex = r.Next(0, tempLibrary.Count);
                _cardModel.drawPile.Add(tempLibrary[choosenIndex]);
                tempLibrary.RemoveAt(choosenIndex);
            }
            _cardModel.discardPile.Clear();
        }
        /// <summary>
        /// 打出一张手牌
        /// </summary>
        /// <param name="index">手牌编号</param>
        public void PlayHandCard(int index)
        {
            if (index < _cardModel.hand.Count)
            {
                CardControllerBase controller = _cardModel.hand[index];
                if (controller.Play())
                {
                    DiscardCard(controller);
                    _cardModel.hand.RemoveAt(index);
                    MonoBehaviour.Destroy(controller.model.viewController.gameObject);
                }
            }
        }

        public void PlaySelectedCard()
        {

        }
        
        public void SelectCard()
        {

        }

        /// <summary>
        /// 将被弃掉手牌复制入弃牌堆
        /// </summary>
        public void DiscardCard(CardControllerBase controller)
        {
            CardModelBase model = controller.CopyModel();
            _cardModel.discardPile.Add(model);
        }

        #endregion
        #region 辅助函数
        /// <summary>
        /// 清除牌堆
        /// </summary>
        void ClearTiles()
        {
            _cardModel.drawPile.Clear();
            _cardModel.discardPile.Clear();
            _cardModel.hand.Clear();
        }
        /// <summary>
        /// 初始化抽牌堆
        /// </summary>
        void CreatePile()
        {
            int count = _cardModel.cardLibrary.Count;
            List<CardModelBase> tempLibrary = new List<CardModelBase>();
            foreach(var content in _cardModel.cardLibrary)
            {
                tempLibrary.Add(content);
            }
            System.Random r = new System.Random();
            for(int i = 0; i < count; i++)
            {
                int choosenIndex = r.Next(0, tempLibrary.Count);
                _cardModel.drawPile.Add(tempLibrary[choosenIndex]);
                tempLibrary.RemoveAt(choosenIndex);
            }
        }

        #endregion
    }
}
